package com.xiaoshuidi.cloud.module.iot.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xiaoshuidi.cloud.framework.common.exception.ServiceException;
import com.xiaoshuidi.cloud.framework.common.pojo.CommonResult;
import com.xiaoshuidi.cloud.framework.common.pojo.PageResult;
import com.xiaoshuidi.cloud.framework.common.util.json.JsonUtils;
import com.xiaoshuidi.cloud.framework.oss.core.OosFileService;
import com.xiaoshuidi.cloud.module.contract.api.ContractApi;
import com.xiaoshuidi.cloud.module.contract.enums.contract.CompanyContractOrderShareTypeEnum;
import com.xiaoshuidi.cloud.module.contract.enums.contract.CustomerTypeEnum;
import com.xiaoshuidi.cloud.module.contract.vo.CustomerInfoVO;
import com.xiaoshuidi.cloud.module.contract.vo.RenterVO1;
import com.xiaoshuidi.cloud.module.iot.controller.admin.report.vo.WaterElectricityReportExportVo;
import com.xiaoshuidi.cloud.module.iot.controller.admin.report.vo.WaterElectricityReportReq;
import com.xiaoshuidi.cloud.module.iot.controller.admin.report.vo.WaterElectricityReportResp;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbDeviceDosageDo;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbWaterElectricityReport;
import com.xiaoshuidi.cloud.module.iot.dal.repository.TbWaterElectricityReportRepository;
import com.xiaoshuidi.cloud.module.iot.enums.ErrorCodeConstants;
import com.xiaoshuidi.cloud.module.iot.enums.PeakValleyEnum;
import com.xiaoshuidi.cloud.module.iot.enums.RedisConstants;
import com.xiaoshuidi.cloud.module.iot.enums.UndertakingPartyEnum;
import com.xiaoshuidi.cloud.module.iot.framework.ConfigValues;
import com.xiaoshuidi.cloud.module.iot.service.CacheService;
import com.xiaoshuidi.cloud.module.iot.service.WaterElectricityReportService;
import com.xiaoshuidi.cloud.module.iot.vo.BaseExportResp;
import com.xiaoshuidi.cloud.module.rooms.api.roomhouse.RoomHouseApi;
import com.xiaoshuidi.cloud.module.rooms.vo.RoomHouseRespVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author Feng
 * @date 2023/9/21
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class WaterElectricityReportServiceImpl implements WaterElectricityReportService {
    private final RoomHouseApi roomHouseApi;
    private final TbWaterElectricityReportRepository waterElectricityReportRepository;
    private final ContractApi contractApi;
    private final ConfigValues configValues;
    private final OosFileService oosFileService;
    private final CacheService cacheService;

    @Override
    public boolean save4PeakValley(Long roomId, String deviceNo, String thirdDeviceNo, String deviceType, Long tenantId, Double amount, Double startReading, Double endReading, String peakValleyType) {
        log.info("插入水电报表：roomId: {}, deviceNo: {}, deviceType: {}, amount: {}, startReading: {}, endReading:{}, peakValleyType:{}", roomId, deviceNo, deviceType, amount, startReading, endReading, peakValleyType);
        if (roomId == null) {
            log.info("插入水电报表 房源ID为空");
            return false;
        }
        //根据roomId获取房间信息
        CommonResult<RoomHouseRespVo> houseInfoResult = roomHouseApi.getRoomHouseinfoById(roomId);
        log.info("插入水电报表 查询到的房屋信息： {}", JsonUtils.toJsonString(houseInfoResult));
        if (houseInfoResult.isSuccess()) {
            RoomHouseRespVo houseInfo = houseInfoResult.getData();
            //根据roomId获取租户信息
            CommonResult<RenterVO1> contractResult = contractApi.getContractRenterListByRoomId(roomId);
            log.info("插入水电报表 查询到的合同信息：{}", JsonUtils.toJsonString(contractResult));

            TbWaterElectricityReport report = new TbWaterElectricityReport();
            this.initReportFromContract(contractResult, report);
            report.setRoomId(roomId);
            report.setRoomName(houseInfo.getFullRoomName());
            report.setApartmentId(houseInfo.getApartmentId());
            report.setApartmentName(houseInfo.getApartmentName());
            report.setDeviceNo(deviceNo);
            report.setDeviceThirdNo(thirdDeviceNo);
            report.setAmount(amount);
            report.setReding(endReading - startReading);
            report.setStartReading(startReading);
            report.setEndReading(endReading);
            report.setPeakValleyType(peakValleyType);
            report.setFeeType(deviceType);
            report.setTenantId(tenantId);
            report.setDeptId(houseInfo.getDeptId());
            waterElectricityReportRepository.save(report);
        }
        return true;
    }

    @Override
    public boolean save(Long roomId, String deviceNo, String thirdDeviceNo, TbDeviceDosageDo dosageDo, String deviceType, Long tenantId) {
        log.info("插入水电报表：roomId: {}, deviceNo: {}, dosageDo: {},  deviceType: {}", roomId, deviceNo, JsonUtils.toJsonString(dosageDo), deviceType);
        if (roomId == null) {
            log.info("房源ID为空");
            return false;
        }
        //根据roomId获取房间信息
        CommonResult<RoomHouseRespVo> houseInfoResult = roomHouseApi.getRoomHouseinfoById(roomId);
        log.info("查询到的房屋信息： {}", JsonUtils.toJsonString(houseInfoResult));
        if (houseInfoResult.isSuccess()) {
            RoomHouseRespVo houseInfo = houseInfoResult.getData();
            //根据roomId获取租户信息
            CommonResult<RenterVO1> contractResult = contractApi.getContractRenterListByRoomId(roomId);
            log.info("查询到的合同信息：{}", JsonUtils.toJsonString(contractResult));

            TbWaterElectricityReport report = new TbWaterElectricityReport();
            this.initReportFromContract(contractResult, report);
            report.setRoomId(roomId);
            report.setRoomName(houseInfo.getFullRoomName());
            report.setApartmentId(houseInfo.getApartmentId());
            report.setApartmentName(houseInfo.getApartmentName());
            report.setDeviceNo(deviceNo);
            report.setDeviceThirdNo(thirdDeviceNo);
            report.setAmount(dosageDo.getAmount());
            report.setReding(dosageDo.getTotalAmount());
            report.setStartReading(dosageDo.getStartAmount());
            report.setEndReading(dosageDo.getEndAmount());
            report.setPeakValleyType(PeakValleyEnum.NORMAL.getCode());
            report.setFeeType(deviceType);
            report.setTenantId(tenantId);
            report.setDeptId(houseInfo.getDeptId());
            waterElectricityReportRepository.save(report);
        }
        return true;
    }

    private void initReportFromContract(CommonResult<RenterVO1> contractResult, TbWaterElectricityReport report) {
        if (contractResult.isSuccess()) {
            RenterVO1 renterVo = contractResult.getData();
            if (renterVo != null) {
                report.setMemberName(renterVo.getRenter());
                //如果是个人合同手机号是个人，如果是企业合同：1、寝室长模式：寝室长手机号；2、企业承担所有：无手机号；3、房屋钱包：无手机号
                if (renterVo.getCustomerType().equals(CustomerTypeEnum.PERSONAL.getCode())) {
                    //个人客户
                    report.setPhone(renterVo.getRenterPhone());
                    report.setAttributableParty(renterVo.getRenter());
                    report.setUndertakingParty(UndertakingPartyEnum.PERSONAL.getCode());
                } else {
                    if (renterVo.getOrderShareMethod().equals(CompanyContractOrderShareTypeEnum.ALL.getCode())) {
                        //企业承担所有
                        report.setAttributableParty(renterVo.getRenter());
                        report.setUndertakingParty(UndertakingPartyEnum.COMPANY.getCode());
                    } else if (renterVo.getOrderShareMethod().equals(CompanyContractOrderShareTypeEnum.RENT_DEPOSIT_ONLY_WITH_PERSONAL.getCode())) {
                        //寝室长承担
                        report.setUndertakingParty(UndertakingPartyEnum.DORMITORY_LEADER.getCode());
                        List<CustomerInfoVO> custmerInfoList = renterVo.getCustmerInfoList();
                        if (CollectionUtil.isNotEmpty(custmerInfoList)) {
                            CustomerInfoVO customerInfoVO = custmerInfoList.get(0);
                            report.setAttributableParty(customerInfoVO.getCustomerName());
                            report.setPhone(customerInfoVO.getCustomerPhone());
                        }
                    } else {
                        //房屋钱包模式
                        report.setUndertakingParty(UndertakingPartyEnum.COHABITANT.getCode());
                        List<CustomerInfoVO> custmerInfoList = renterVo.getCustmerInfoList();
                        if (CollectionUtil.isNotEmpty(custmerInfoList)) {
                            String memberName = custmerInfoList.stream().map(s -> s.getCustomerName()).collect(Collectors.joining("/"));
                            report.setAttributableParty(memberName);
                        }

                    }
                }
            }
        }
    }

    @Override
    public PageResult<WaterElectricityReportResp> page(WaterElectricityReportReq req) {
        IPage<TbWaterElectricityReport> page = waterElectricityReportRepository.page(req);
        PageResult<WaterElectricityReportResp> result = new PageResult<>();
        List<TbWaterElectricityReport> records = page.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {
            List<WaterElectricityReportResp> resps = records.stream().map(s -> {
                WaterElectricityReportResp resp = new WaterElectricityReportResp();
                BeanUtils.copyProperties(s, resp);
                resp.setDeductionTime(LocalDateTimeUtil.format(s.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
                return resp;
            }).collect(Collectors.toList());
            result.setList(resps).setTotal(page.getTotal());
        }
        return result;
    }

    @Override
    public void export(WaterElectricityReportReq req, String key) {
        try {
            if (req.getStartTime() == null || req.getEndTime() == null) {
                LocalDateTime now = LocalDateTime.now();
                LocalDateTime startTime = now.plusMonths(-1);
                req.setStartTime(LocalDateTimeUtil.format(startTime, "yyyy-MM-dd"));
                req.setEndTime(LocalDateTimeUtil.format(LocalDateTime.now(), "yyyy-MM-dd"));
            }
            long count = waterElectricityReportRepository.exportCount(req);
            if (count <= 0) {
                throw new ServiceException(ErrorCodeConstants.REPORT_DATA_EXISTS);
            }
            int pageSize = 20000;
            int totalPage = (int) count / pageSize;
            if (count % pageSize != 0) {
                totalPage++;
            }
            String fileName = configValues.getNfsPath() + File.separator + "水电报表明细.xlsx";
            ExcelWriter excelWriter = EasyExcel.write(fileName, WaterElectricityReportExportVo.class).build();
            WriteSheet sheet = EasyExcel.writerSheet("sheet1").build();
            for (int i = 1; i <= totalPage; i++) {
                req.setPageNo(i);
                req.setPageSize(pageSize);
                IPage<TbWaterElectricityReport> page = waterElectricityReportRepository.page(req);
                List<TbWaterElectricityReport> records = page.getRecords();
                List<WaterElectricityReportExportVo> vos = records.stream().map(s -> {
                    WaterElectricityReportExportVo vo = new WaterElectricityReportExportVo();
                    BeanUtils.copyProperties(s, vo);
                    vo.setDeductionTime(LocalDateTimeUtil.format(s.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
                    return vo;
                }).collect(Collectors.toList());
                excelWriter.write(vos, sheet);
            }
            excelWriter.finish();
            //上传到oos返回URL
            String url = oosFileService.oosUploadFile(new File(fileName));
            BaseExportResp resp = new BaseExportResp();
            resp.setUrl(url);
            resp.setFileName("水电报表明细.xlsx");
            String redisKey = String.format(RedisConstants.WaterElectricityReportExport, key);
            resp.setCode(0);
            cacheService.putObject(redisKey, resp, 2000);
        } catch (Exception e) {
            log.error("水电报表明细导出失败： {}", e);
        }
    }
}
